package com.ig.presentacion.modelos.desembolso.calculos;

import ig.ejb.metrica.da.editor.dao.abs.Utilidades;
import com.ig.presentacion.modelos.desembolso.calculos.interfaces.IModalidad;
import javax.swing.JOptionPane;


/**
 * Clase encargada de generar los planes de amortizaci?n
 * 	1	Cuota Variable, TasaVariable
 * 	2	Cuota Variable, Tasa Fija
 * 	3	Cuota Fija, Tasa Fija
 *
 * Cada uno de estos metodos supone
 * 	que el interes ya esta convertido a la frecuencia
 *
 * @author jsanchez
 *
 */
public class CuotaFijaTasaFija{
    private int periodoGracia=0;
    private Fechas fechas= null;
    boolean debug=false;
    
    public CuotaFijaTasaFija(Fechas fechas){
        this.fechas= fechas;
    }
    
    public void setPeriodoGracia(int periodoGracia) {
        this.periodoGracia = periodoGracia;
    }
    
    public CuotaFijaTasaFija(Fechas fechas,boolean debug){
        this.fechas= fechas;
        this.debug=debug;
    }
    
    
    private boolean validarFrecuencias(Integer frecuenciaPagoCapital,Integer frecuenciaPagoInteres,Integer frecuenciaPlazo) throws Exception{
        boolean ok=false;
        if(frecuenciaPagoCapital>=frecuenciaPagoInteres){
            if(frecuenciaPlazo<frecuenciaPagoCapital){
                throw new Exception("PlanAmortizacion:La frecuencia de pago de interes NO PUEDE ser mayor que la frecuencia del pazo");
            }else
                return true;
        }else
            throw new Exception("PlanAmortizacion:La frecuencia de pago de interes NO PUEDE ser menor que la frecuencia de pago de capital");
    }
    
    /**
     * calcula el plan de amortizacion para cuotas fijas y tasa fija
     *
     * @param monto 				: valor	desembolsado
     * @param interesVariable	: vector de intereses ya convertidos a frecuencia de pago
     * @param plazo				: frecuencia de pago
     * @modalidad				: vencida o anticipada
     * @return					: matriz con filas=plazo.leng & columnas 5[fecha, cuota, interes, capital, saldocapital]
     */
    public Object[][] calcularPlanCuotaFijaTasaFija(Double monto, Double interes, Integer plazo,Integer modalidad,Integer frecuenciaPagoCapital,Integer frecuenciaPagoInteres,Integer frecuenciaPlazo)throws Exception{
        this.fechas.setNoUno(false);
        this.monto=monto;
        if(validarFrecuencias(frecuenciaPagoCapital,frecuenciaPagoInteres,frecuenciaPlazo)){
            //Marcela Sep 20 2010
            /*if(plazo%frecuenciaPagoCapital==1){
                throw new Exception("PlanAmortizacion:El plazo no corresponde a la fecuencia de pago capital");
            }else if(frecuenciaPagoCapital.equals(frecuenciaPagoInteres) && frecuenciaPagoInteres.equals(frecuenciaPlazo)){*/
                return calcular(monto, interes, plazo,null,modalidad,frecuenciaPagoCapital,frecuenciaPagoInteres,frecuenciaPlazo);
            /*}else{
                int plazoTotal=0;
                int plazoMinimo=0;
                plazoTotal=((plazo*frecuenciaPlazo)/frecuenciaPagoCapital)*(frecuenciaPagoCapital/frecuenciaPagoInteres);
                plazoMinimo=((plazo*frecuenciaPlazo)/frecuenciaPagoCapital)*frecuenciaPagoInteres;
                plazoMinimo=plazoMinimo/frecuenciaPagoInteres;
                this.fechas.setNoUno(true);
                Object[][] object=calcular(monto, interes, plazoMinimo,null,modalidad,frecuenciaPagoCapital,frecuenciaPagoInteres,frecuenciaPlazo);
                this.fechas.setNoUno(false);
                return setCuotasAdicionales(object,plazoTotal,frecuenciaPagoInteres,frecuenciaPagoCapital);
            }*/
        }
        return null;
    }
    private Double monto=null;
    private Object[][] setCuotasAdicionales(Object[][] object,Integer totalCuotas,Integer frecuenciaPagoInteres,Integer frecuenciaPagoCapital){
        Object[][] myObject=new Object[totalCuotas][6];
        Double myMonto=this.monto;
        fechas.setTipoFrecuencia(frecuenciaPagoInteres);
        int pivote=frecuenciaPagoCapital/frecuenciaPagoInteres;
        int secuencia=1;
        int j=0;
        for (int i = 0; i < totalCuotas; i++) {
            myObject[i][0]=i+1;
            myObject[i][1]=fechas.getFormatoString();
            if(pivote==secuencia){
                secuencia=1;
                myObject[i][2]=object[j][2];
                myObject[i][3]=object[j][3];
                myObject[i][4]=object[j][4];
                if(object.length-1>j)
                    j++;
            }else{
                myObject[i][2]=object[j][3];
                myObject[i][3]=object[j][3];
                myObject[i][4]=0;
                secuencia++;
            }
            Object a=myObject[i][4];
            if(myObject[i][4] instanceof Double){
                myMonto=myMonto-(Double)myObject[i][4];
            }else if(myObject[i][4] instanceof Integer){
                myMonto=myMonto-(Integer)myObject[i][4];
            }else if(myObject[i][4] instanceof Long){
                myMonto=myMonto-(Long)myObject[i][4];
            }
            myObject[i][5]=myMonto;
        }
        return myObject;
    }
    
    private Double CUOTA=null;
    private Object[][] calcular(Double monto, Double interes,Integer plazo,Integer newPlazo,Integer modalidad,Integer frecuenciaPagoCapital,Integer frecuenciaPagoInteres,Integer frecuenciaPlazo) throws Exception{
        Double sub1;
        Double sub2;
        Double sub3;
        Double cuotas=0.0;
        fechas.setTipoFrecuencia(frecuenciaPagoInteres);
        
        if(modalidad==IModalidad.VENCIDA){
            sub1=monto;
            sub2=Math.pow(1+interes,plazo)-1;
            sub3=interes*Math.pow((1+interes),plazo);
            if(getCUOTA()==null)
                cuotas=(sub1/(sub2/sub3));
            else
                cuotas=getCUOTA();
        }else if(modalidad==IModalidad.ANTICIPADA){
            sub1=monto;
            sub2=Math.pow(1+interes,plazo)-1;
            sub3=interes*Math.pow((1+interes),(plazo-1));
            if(getCUOTA()==null)
                cuotas=(sub1/(sub2/sub3));
            else
                cuotas=getCUOTA();
            monto-=cuotas;
        }
        cuotas=Double.valueOf(/*Math.round(*/cuotas/*)*/);
        Double calculoInteres=0.0;
        Double calculoCapital=0.0;
        Double saldo=monto;
        Double interestmp=0.0;
        Object[][] vPlan= new Object[plazo][6];
        
        int Ncuota=0;
        for (int i = 1; i <= plazo; i++) {
            vPlan[i-1][0]=Double.valueOf(i);
            vPlan[i-1][1]=fechas.getFormatoString();
            calculoInteres = Utilidades.redondear(Double.valueOf(saldo*interes),0);
            interestmp=calculoInteres;
// Marcela Sep 20 de 2010
/*
            if(i<=periodoGracia){
                vPlan[i-1][2]=cuotas-calculoInteres;
                calculoInteres=0.0;
            }else
                vPlan[i-1][2]=cuotas; */
            
            vPlan[i-1][2]=calculoInteres;
            vPlan[i-1][3]=calculoInteres;


            if(i<plazo /*|| modalidad == Modalidades.VENCIDA*/)
                //calculoCapital=cuotas-interestmp;
                calculoCapital=0.0;
            else
                calculoCapital=saldo;
  
            vPlan[i-1][4]=calculoCapital;
            saldo-=calculoCapital;
            vPlan[i-1][5]=saldo;
        }
        if(plazo>0){
            Double vUltimaCuota=(Double)vPlan[plazo-1][2];
            Double vUltimoInteres=(Double)vPlan[plazo-1][3];
            Double vUltimoSaldo=(Double)vPlan[plazo-1][4];
            
            if(vUltimaCuota.doubleValue()>(vUltimoInteres+vUltimoSaldo) || vUltimaCuota.doubleValue()<(vUltimoInteres+vUltimoSaldo)){
                vPlan[plazo-1][2]=vUltimoInteres+vUltimoSaldo;
            }
        }
        if(debug){
            System.out.println("VALOR CUOTA:"+cuotas);
            System.out.println("VALOR MONTO:"+monto);
            System.out.println("		No Cuota	FECHA			CUOTAS		INTERES		CAPITAL		SALDO");
            System.out.println("	********************************************************************************************************************************");
            for (int i = 0; i < plazo; i++) {
                String str="";
                for (int j = 0; j < 6; j++) {
                    if(j==1){
                        str+="		"+vPlan[i][j];
                    }else
                        str+="		"+Math.round((Double)vPlan[i][j]);
                }
                System.out.print(str+"\n");
            }
            System.out.println("	********************************************************************************************************************************");
        }
        return vPlan;
    }
    
    
    
//    /**
//     * calcula el plan de amortizacion para cuotas varibles y tasa fija
//     * @param monto 				: valor	desembolsado
//     * @param interes			: interes ya convertido a frecuencia de pago
//     * @param plazo				: es la frecuencia de pago
//     * @param capital			: vector de abonos a capital en frecuencias preferidas
//     * 								ej:
//     *      								Double[] vector= new Vector[4];
//     * 									vector[1-1]=2000000;
//     * 									vector[4-1]=2000000;
//     * 										No implica que las demas pocisiones sean nulas.
//     * @return					: matriz con el plan acalculado
//     */
//    public Object[][] calcularPlanCuotaVariableTasaFija(Double monto, double interes, Integer plazo,Double[] abonoCapital){
//
//    	Double[] capitalReal= new Double[plazo];
//    	for (int i = 0; i < capitalReal.length; i++) {
//		if(abonoCapital.length>i){
//	    		if(abonoCapital[i]==null) capitalReal[i]=Double.parseDouble("0");
//			else capitalReal[i]=abonoCapital[i];
//		}else capitalReal[i]=Double.parseDouble("0");
//	}
//
//	Double calculoInteres=0.0;
//	Double calculoCapital=0.0;
//	Double saldo=monto;
//
//	Object[][] vPlan= new Object[plazo][6];
//
//	int Ncuota=0;
//	for (int i = 1; i <= plazo; i++) {
//		Ncuota=0;
//		vPlan[i-1][Ncuota]=Double.valueOf(i);
//			Ncuota++;
//        vPlan[i-1][Ncuota]=fechas.getFecha();
//			Ncuota++;
//		if(i<=periodoGracia)	calculoInteres=0.0;
//		else calculoInteres=Double.valueOf(Math.round(saldo*interes));
//		vPlan[i-1][Ncuota]=capitalReal[i-1]+calculoInteres;
//			Ncuota++;
//		vPlan[i-1][Ncuota]=calculoInteres;
//			Ncuota++;
//		calculoCapital=capitalReal[i-1];
//		vPlan[i-1][Ncuota]=calculoCapital;
//			Ncuota++;
//		saldo-=calculoCapital;
//		vPlan[i-1][Ncuota]=saldo;
//			Ncuota++;
//	}
//	if(debug){
//		System.out.println("		CUOTA		FECHA			CUOTAS		INTERES		CAPITAL		SALDO");
//		System.out.println("	*********************************************************************************************");
//	}
//		for (int i = 0; i < plazo; i++) {
//			for (int j = 0; j < 6; j++) {
//				if(j==1){
//					String fecha=null;;
//					String myFecha=String.valueOf(Math.round((Double)vPlan[i][j]));
//					if(myFecha.length()==8){
//						fecha=myFecha.substring(0,2)+"/"+myFecha.substring(2,4)+"/"+myFecha.substring(4,8);
//						if(debug)System.out.print("		"+fecha);
//					}
//					if(myFecha.length()==7){
//						fecha=myFecha.substring(0,1)+"/"+myFecha.substring(1,3)+"/"+myFecha.substring(3,7);
//						if(debug)System.out.print("		"+fecha);
//					}
//					vPlan[i][j]=fecha;
//				}else
//					if(debug){
//						System.out.print("		"+Math.round((Double)vPlan[i][j]));
//						System.out.print("\n");
//					}
//			}
//		}
//		if(debug)System.out.println("	*********************************************************************************************");
//	//}
//		return vPlan;
//}
//
//	/**
//	 * @param fechaPagoInicial
//	 *
//	 * Ejemplo: 05052006
//	 */
//	public void setFechaPagoInicial(String fechaPagoInicial) {
//		fechas.setDia(fechaPagoInicial.substring(0,2));
//		fechas.setMes(fechaPagoInicial.substring(2,4));
//		fechas.setAnno(fechaPagoInicial.substring(4,8));
//	}
    
//	/**
//	 * @param frecuencia
//	 * :puede ser
//	 * 	Fechas.DIARION=1
//	 * 	Fechas.SEMANAL=2
//	 * 	Fechas.MENSUAL=3
//	 * 	Fechas.TRIMESTRAL=4
//	 * 	Fechas.SEMESTRAL=5
//	 * 	Fechas.ANUAL=6
//	 */
//	public void setTipoFrecuencia(int tipoFrecuencia) {
//		this.fechas.setTipoFrecuencia(tipoFrecuencia);
//	}
    
//	/**
//	 * tipo de calendario para el calculos de los intereses
//	 *
//	 * @param calendarioCalculoInteres
//	 * 	puedes ser:
//	 *
//	 * 	Calendarios.CALENDARIO_REAL=1 todos los a?os son de 365 o 366 dias y los meses de 28, 29, 30, 31 dias
//	 * 	Calendarios.CALENDARIO_COMERCIAL=2 todos los a?os tines 360 dias u los meses de 30 dias
//	 * 	Calendarios.CALENDARIO_365=3 todos los meses tienen 365 dias y los meses de 28, 30, 31 dias
//	 */
//	public void setCalendarioCalculoInteres(int calendarioCalculoInteres) {
//		this.fechas.setCalendarioCalculoInteres(calendarioCalculoInteres);
//	}
    
//    /**
//     * calcula el plan de amortizacion para cuotas varibles y tasa variables
//     *
//     * @param monto 				: valor	desembolsado
//     * @param interesVariable	: vector de intereses ya convertidos a frecuencia de pago
//     * @param plazo				: frecuencia de pago
//     * @return					: matriz con filas=plazo.leng & columnas 5[fecha, cuota, interes, capital, saldocapital]
//     */
//    public Object[][] calcularPlanCuotaVariableTasaVariable(double monto, Double[] interesVariable, int plazo){
//
//	Double cuotas=(monto/plazo);
//	if(debug){
//		System.out.println("VALOR MONTO:"+monto);
//	}
//	Double calculoInteres=0.0;
//	Double calculoCapital=0.0;
//	Double saldo=monto;
//	Object[][] vPlan= new Object[plazo][6];
//
//	Double[] IntereesReal= new Double[plazo];
//	for (int i = 0; i < IntereesReal.length; i++) {
//		if(interesVariable.length>i){
//    			if(interesVariable[i]==null)
//    				IntereesReal[i]=Double.parseDouble("0");
//    			else IntereesReal[i]=interesVariable[i];
//		}else IntereesReal[i]=Double.parseDouble("0");
//	}
//
//
//	int Ncuota=0;
//	for (int i = 1; i <= plazo; i++) {
//		Ncuota=0;
//		vPlan[i-1][Ncuota]=Double.valueOf(i);
//			Ncuota++;
//		if(i<=periodoGracia)	calculoInteres=0.0;
//		else calculoInteres=Double.valueOf(Math.round(saldo*IntereesReal[i-1]));
//		vPlan[i-1][Ncuota]=fechas.getFecha();
//			Ncuota++;
//		vPlan[i-1][Ncuota]=cuotas+calculoInteres;
//			Ncuota++;
//		vPlan[i-1][Ncuota]=calculoInteres;
//			Ncuota++;
//		calculoCapital=cuotas;
//		vPlan[i-1][Ncuota]=calculoCapital;
//			Ncuota++;
//		saldo-=calculoCapital;
//		vPlan[i-1][Ncuota]=saldo;
//			Ncuota++;
//	}
//	if(debug){
//		System.out.println("		CUOTA		FECHA			CUOTAS		INTERES		CAPITAL		SALDO");
//		System.out.println("	*********************************************************************************************");
//	}
//		for (int i = 0; i < plazo; i++) {
//			for (int j = 0; j < 6; j++) {
//				if(j==1){
//					String fecha=null;;
//					String myFecha=String.valueOf(Math.round((Double)vPlan[i][j]));
//					if(myFecha.length()==8){
//						fecha=myFecha.substring(0,2)+"/"+myFecha.substring(2,4)+"/"+myFecha.substring(4,8);
//						if(debug)System.out.print("		"+fecha);
//					}
//					if(myFecha.length()==7){
//						fecha=myFecha.substring(0,1)+"/"+myFecha.substring(1,3)+"/"+myFecha.substring(3,7);
//						if(debug)System.out.print("		"+fecha);
//					}
//					vPlan[i][j]=fecha;
//				}else
//					if(debug){
//						System.out.print("		"+Math.round((Double)vPlan[i][j]));
//						System.out.print("\n");
//					}
//			}
//		}
//		if(debug)System.out.println("	*********************************************************************************************");
//		return vPlan;
    
    public Double getCUOTA() {
        return CUOTA;
    }
    
    public void setCUOTA(Double _CUOTA) {        
        this.CUOTA = _CUOTA;
    }
    
}